// 两种方式来创建对象：陈述方式和构造器方式
/* var myObj = {
	key: value
	// ...
};

var myObj1 = new Object();
myObj1.key = value; */

// js中的 基本类型有Object，String，Number，Boolean，null，undefined。注意string，number，boolean，null，undefined自身都不是对象
console.log(typeof String);//function

// 复杂基本类型 function，array

// 内建对象：其实这些内建对象就是构造函数
/* String
Number
Boolean
Object
Function
Array
Date
RegExp
Error */
console.log(typeof Array)
console.log(typeof Date);

// 这里的字符串只是一个常量，语言自动将他和String关联。Number、boolean会做同样事
var strPrimitive = "I am a string";
console.log(typeof strPrimitive);							// "string"
console.log(strPrimitive instanceof String);

// 在对象中只是记录了属性的名称和数据存储的位置

// Array数组是一个对象

// 复制对象
// 在js上为什么没有提供一个简单的copy函数来解决所有深度拷贝的拷贝问题？1、可能存在的嵌套引用；2、拷贝函数到底有没有意义
// 所以现在最可靠的深度拷贝方式是JSON安全的拷贝
var someObj = {
	fn: function () {
		console.log("d");
	},
	a: ""
}
var newObj = JSON.parse(JSON.stringify(someObj));
// newObj.fn(); 拷贝后没有函数

// 浅拷贝
var newObj = Object.assign({}, someObj);
newObj.fn();



// 属性描述符
(function () {
	console.log("==============property descriptor=============");
	var myObj = {
		a: "aaa"
	}

	console.log(JSON.stringify(Object.getOwnPropertyDescriptor(myObj, "a")));

	Object.defineProperty(myObj, "a", {
		value: 2,
		writable: true,
		configurable: true,
		enumerable: true
	})

	console.log(myObj.a);
})();


(function () {
	console.log("==================writable=false=================")
	var myObj = {};
	Object.defineProperty(myObj, "a", {
		value: 2,
		writable: false,//不允许修改
		configurable: true,
		enumerable: true
	})
	console.log(myObj.a);
	myObj.a = 4;
	console.log(myObj.a);
})();


(function () {
	console.log("===================configurable=false0=====================");
	var myObj = {
		a: 3
	};
	console.log(myObj.a);
	Object.defineProperty(myObj, "a", {
		value: 23,
		writable: true,
		configurable: false,
		enumerable: true
	})
	myObj.a = 5;
	console.log(myObj.a);
	// 如果再修改描述符，则报错
	// 使用delete删除属性也会报错
	/* Object.defineProperty(myObj,"a",{
		value: 23,
		writable: true,
		configurable: true,
		enumerable: true
	}); */
})();

// Object.preventExtensions( myObject )禁止添加新的属性
// Object.seal(..)禁止添加新的属性，同时也不能配置现有属性，但是可以修改现有属性的值
// Object.freeze(..) 禁止添加属性，禁止配置属性，禁止修改属性